package xyz.riceball.common.aop;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import xyz.riceball.common.entity.po.SysLogPO;
import xyz.riceball.common.service.SysLogService;
import xyz.riceball.framework.core.annotation.RbLog;
import xyz.riceball.framework.core.context.WebContextHolder;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * <p>
 * 日志切面
 * </p>
 *
 * @author xiaovcloud
 * @since 2022/7/26 19:50
 */
@Configuration
@Aspect
@Slf4j
public class LogAspect {

    @Resource
    SysLogService sysLogService;

    @Pointcut("@annotation(xyz.riceball.framework.core.annotation.RbLog)")
    public void log() {
    }

    @AfterThrowing(value = "log()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e) throws NoSuchMethodException {
        SysLogPO sysLogPO = new SysLogPO();
        //设置注解中的信息
        Signature signature = joinPoint.getSignature();
        MethodSignature msg = (MethodSignature) signature;
        Object target = joinPoint.getTarget();
        //获取注解标注的方法
        Method method = target.getClass().getMethod(msg.getName(), msg.getParameterTypes());
        //通过方法获取注解
        RbLog annotation = method.getAnnotation(RbLog.class);
        String message = annotation.description();
        sysLogPO.setMsg(message);
        if (annotation.isSaveRequestData()) {
            Object[] args = joinPoint.getArgs();
            String argsJson = JSONUtil.toJsonStr(args);
            sysLogPO.setParams(argsJson);
        }
        sysLogService.saveErrorSysLog(sysLogPO, WebContextHolder.getHttpServletRequest(), e);
    }


    @AfterReturning("log()")
    public void around(JoinPoint joinPoint) throws Throwable {
        //设置参数
        SysLogPO sysLogPO = new SysLogPO();

        //设置注解中的信息
        Signature signature = joinPoint.getSignature();
        MethodSignature msg = (MethodSignature) signature;
        Object target = joinPoint.getTarget();
        //获取注解标注的方法
        Method method = target.getClass().getMethod(msg.getName(), msg.getParameterTypes());
        //通过方法获取注解
        RbLog annotation = method.getAnnotation(RbLog.class);
        String message = annotation.description();
        sysLogPO.setMsg(message);
        if (annotation.isSaveRequestData()) {
            Object[] args = joinPoint.getArgs();
            String argsJson = JSONUtil.toJsonStr(args);
            sysLogPO.setParams(argsJson);
        }
        sysLogService.saveInfoSysLog(sysLogPO, WebContextHolder.getHttpServletRequest());
    }

}
